#!/usr/bin/perl

sub find_match_line
  {
     
     my $sender = $_[0];
     my $packet_id = $_[1];
     my $local_line_count = 0;

     if ($debug_print){
     	print ("Running find_match_line sub with arguments : $sender ; $packet_id ; \n");
     }

    while ($local_line_count < @file_lines){
		my @line_parts = split(/;/,$file_lines[$local_line_count]);      
		if ($debug_print){
			print ("line_parts[4] = $line_parts[4] ; line_parts[1] = $line_parts[1] ; line_parts[3] = $line_parts[3] \n");
		}
		if (($line_parts[4] eq " Sent" )&&($line_parts[1]== $sender)&&($line_parts[3]== $packet_id)){
			if ($debug_print){
				print ("Found match for sender $sender, packet $packet_id \n");
				print ("The matching line is : $file_lines[$local_line_count] \n ");
			}
			return $file_lines[$local_line_count];
		}
		$local_line_count++;
	}
    print ("No match for Recieved packet, which was sent by $sender with packet ID $packet_id \n");
  }


sub calc_stats
{
	my $new_throuput = $_[0];
	my $new_latency = $_[1];
	my $new_sl = $_[2];
	my $packet_flits_num = $_[3];

	my $size_range;
	if ($packet_flits_num <= $small_pack_max){
		$size_range = 0;
	}	
	if (($packet_flits_num > $small_pack_max) && ($packet_flits_num <= $med_pack_max)){
		$size_range = 1;
	}
	if ($packet_flits_num > $med_pack_max){
		$size_range = 2;
	}	

	$latency_global += $new_latency;
	$sl_latency[$new_sl][$size_range] += $new_latency;
	$throughput_global += $new_throuput;
	$sl_throughput[$new_sl][$size_range] += $new_throuput;
	$packet_throughput_global += (1/$new_latency);
	$sl_packet_throughput[$new_sl][$size_range]+= (1/$new_latency);
	$sl_packet_counters[$new_sl][$size_range] += 1;
}


sub calc_total_stats()
{
	my $total_pack_num = 0;
	
	for ($i=0; $i < $sl_num ; $i++){ # Loop of SL
		for ($j=0; $j < $num_of_pack_sizes ; $j++){ # Loop of Packet Sizes Group
			if ($sl_packet_counters[$i][$j] != 0){
			    $sl_latency[$i][$j] /= $sl_packet_counters[$i][$j];
			    $sl_throughput[$i][$j] /= $sl_packet_counters[$i][$j];
				$sl_packet_throughput[$i][$j] /= $sl_packet_counters[$i][$j];
			}
			else{
		        $sl_latency[$i][$j] = 0;
			    $sl_throughput[$i][$j] = 0;
				$sl_packet_throughput[$i][$j] = 0;
			}
			$total_pack_num+=$sl_packet_counters[$i][$j];
		}
   }

   $latency_global /= $total_pack_num;
   $throughput_global /= $total_pack_num;
   $packet_throughput_global /= $total_pack_num;
}

sub print_stats()
{

	my @size_group_names;
	$size_group_names[0] = join("",('3 to ',$small_pack_max));
	$size_group_names[1] = join("",($small_pack_max+1,' to ',$med_pack_max));
	$size_group_names[2] = join("",($med_pack_max+1,' and more'));
	
	print FILE_OUT ("\n");
	print FILE_OUT ("Packets Numbers\n");
    print FILE_OUT (";");
    for ($j=0;$j<$num_of_pack_sizes;$j++){
		print FILE_OUT ("$size_group_names[$j];");
    }
    print FILE_OUT ("\n");
    for ($i=0; $i < $sl_num ; $i++){
		print FILE_OUT ("SL $i;");
			for ($j=0;$j<$num_of_pack_sizes;$j++){
				print FILE_OUT ($sl_packet_counters[$i][$j],";") ;
			}
		print FILE_OUT ("\n");
    }

    print FILE_OUT "\nTotal Latency (ns) ;",$latency_global*1e-3,"\n\n" ;    

    print FILE_OUT (";");
    for ($j=0;$j<$num_of_pack_sizes;$j++){
		print FILE_OUT ("$size_group_names[$j];");
    }
    print FILE_OUT ("\n");

    for ($i=0; $i < $sl_num ; $i++){
		print FILE_OUT ("SL $i Latency;");
		for ($j=0;$j<$num_of_pack_sizes;$j++){
    		print FILE_OUT ($sl_latency[$i][$j]*1e-3,";") ;
		}
		print FILE_OUT ("\n");
    }
    
    
	print FILE_OUT "\nTotal Throughput (Mbps);",$throughput_global*1e6,"\n\n" ;
	
    print FILE_OUT (";");
    for ($j=0;$j<$num_of_pack_sizes;$j++){
		print FILE_OUT ("$size_group_names[$j];");
    }
    print FILE_OUT ("\n");

    for ($i=0; $i < $sl_num ; $i++){
		print FILE_OUT ("SL $i Throughput;");
		for ($j=0;$j<$num_of_pack_sizes;$j++){			
			print FILE_OUT ($sl_throughput[$i][$j]*1e6,";") ;
    	}
		print FILE_OUT ("\n");
    }

	print FILE_OUT "\nTotal Pacekt Throughput (Packets / usec);",$packet_throughput_global*1e6,"\n\n";

    print FILE_OUT (";");
    for ($j=0;$j<$num_of_pack_sizes;$j++){
		print FILE_OUT ("$size_group_names[$j];");
    }
    print FILE_OUT ("\n");

    for ($i=0; $i < $sl_num ; $i++){
		print FILE_OUT ("SL $i Packet Throughput;");
		for ($j=0;$j<$num_of_pack_sizes;$j++){
			print FILE_OUT ($sl_packet_throughput[$i][$j]*1e6,";") ;
    	}
		print FILE_OUT ("\n");
    }
}

sub main
  {
    # Global Variables
    $debug_print = 0;
    $flit_size = 8;
    
    # Packet Size Ranges
    $small_pack_max = 15;
    $med_pack_max   = 127;

    # Statistics Global Variables
    $latency_global;
    @sl_latency;
    $throughput_global;
    @sl_throughput;
	$packet_throughput_global;
	@sl_packet_throughput;
    @sl_packet_counters;
    $sl_num = 4;
    $num_of_pack_sizes = 3;

    open (FILE_IN,"simulation.log");
    open (FILE_OUT,">data_in.txt");
    print FILE_OUT "ModuleID In;ModuleID Out;Packet ID;Flit Number;Service Level;Send Time;Recieve Time;Latency;Throughput;\n";
  
    @file_lines = <FILE_IN>;    

    my $line_count = 0;

	while ($line_count < @file_lines){

		$line_in = $file_lines[$line_count];
		@line_fields = split(/;/,$line_in);
		$line_count++;

		if ($line_fields =~ 7){
			print ("Wrong number of fields in line, (not 7). \n The line is : \n $line_in \n");
		}
	
		if ($line_fields[4] eq " Received"){
			@new_line = ($line_fields[1],$line_fields[2],$line_fields[3],$line_fields[5],$line_fields[6],"",$line_fields[0],"");

			if ($debug_print){
				print("Recieved Line = @new_line \n" );
				print("sender = $line_fields[2], pack_id = $line_fields[3] \n");
			}

		$matching_line = find_match_line($line_fields[2],$line_fields[3]);

		@matching_line_split = split(/;/,$matching_line);
		$new_line[5] = $matching_line_split[0];
		$new_line[7] = $new_line[6] - $new_line[5];
		
		if ($debug_print){
			print ("New format - only recieved is : \n $new_line_single \n ");
		}

		$packet_latency = $new_line[7];
		$packet_flits = $new_line[3];	
		$packet_thru = ($packet_flits * $flit_size) / $packet_latency;
		$packet_sl = $new_line[4];	
		@new_line = (@new_line,$packet_thru);

		$new_line_single = join(";",@new_line);

		calc_stats($packet_thru,$packet_latency,$packet_sl,$packet_flits);
			print FILE_OUT ("$new_line_single \n");
		}
    }

    calc_total_stats();
    print_stats();
   
    close(FILE_IN);
    close(FILE_OUT);
	
	print "Done Processing :)";
	
  }

main();
<>;
